
/*
*Pool Public Licence version 0.1 or later
*Released on 20th April 2008.
*Any voilations can be repoted at paritosh@wikiocean.net
*What is treated as voilations can be found at www.wikiocean.net/ppl1-voilations* 
******************************************************************************
* The contents of this file are subject Affero GPL v3 and later with additional conditions.
* The additional conditions are to be considered as part of the Affero GPL v3 and later.
* The additional conditions will supersede the Affero GPLv3 and later in case of conflict.
* ("License"); You may not use this file except in compliance with the License
* You may obtain a copy of the License at http://www.gnu.org/licenses/agpl.html
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
* The Initial Developer of the Original Code is Paritosh Pungaliya.
* created by Paritosh Pungaliya are Copyright (C) Paritosh Pungaliya; All Rights Reserved.
* Contributions are Copyright (C) 2001-2008 Paritosh Pungaliya.

* Objective of the additional terms (license) 
* 1) Is to extend the software freedom to freedom to work.
* 2) To ensure that knowledge is free from monopoly of agencie(s).
* 3) To avoid a situation where big corporates or investors can buy out free software groups and companies and then start milking the communities built around it.
* (this trend can be seen how the openness changes in companies that get Venture Capital funding.)
* (if you agree to this logic I invite you to our group to work together)

* Additional conditions
*  0) Source code will also include
* 	a) data dictionaries, data ontologies which are used to alter the behavior of code or to control           the features of application.
* 	b) Any code generated or derived automatically or manually from this code or logic
*  1) The revenue generated by deploying, implementing , selling services and other activities
*  	 based on this source code should be shared 100%, between the people working on it.
*  2) Capital invested should be given only fixed rate of return or linked to revenue/surplus growth for limited time.
*  3) People working on the project should always have an option to replace the capital provider in full or part with lower cost capital.
*  4) Their should not be any ownership which can be sold as a claim on future profit to be generated from the work of people working on the code.
*  5) Brand thus generated should belong to the group.
*  6) For old and new members revenue sharing should be equal for same work equivalent.
*  7) The share of revenue should be decided by bidding for work before allocation of work within the group.
*  8) Before bidding various method of measuring the work should be clearly defined and published in public domain. Any change in process should also be publised in public domain imediately.
*  9) All data related to to revenue sharing should be published as and when generated in public domain.
*  10) For group of people having size more than 10 people will have to make it open online for others to participate in bids. 
*  11) All people involved in related and sub project will be treated as a group.
*  12) Once this license is being used for a certain code then all and any other software services being provided by the group should complusorilly come under 100% revenue sharing.
*  13) Cross subsidization should not happen under this revenue share, no additional benefit should be drawn from the people, by the employing agency.
*  14) Any position or knowledge or legal structure created relating to people working on code, which adversely affects the spirit of 100% revenue share will be treated as a violation.
*  15) Revenue sharing defined.
*     a) includes direct revenue and also intangible gains like brand, and organization.
*     b) No personal judgment should be involved in judging the distribution of revenue.It has to be pre-defined formula based.
*     c)100% of revenue should be shared before expenses and recievers should have control over what expenses to incur.
*     d)For the work done in any month by contributing group member, working on any project can be given revenue share from the work done by the group, for a maximum of 18 months after that month.
*     e)Revenue should be apportioned to the month in which work is done and not when received.
*  The group fulfilling the above conditions also has to be a wiki ecosystem further defined in www.wekosystem.org or read about Wekosystem at www.wikiocean.net

*  ******************************************************************************
*/  
package smsBean;

import java.sql.ResultSet;
import java.sql.SQLException;

import java.util.Hashtable;
import java.util.Vector;

import control.Command;
import control.Dictionary;
import control.SpecialCharacter;

import timer.ExecutionTimer;
import timer.TimerRecordFile;
import utility.CharAt;
import utility.ConvertToLower;
import utility.Index;
import database.RecordSearch;
import dbmanager.Column;
import dbmanager.GetIdName;

public class SmsDictionary extends SubSmsBean
{	
	
	private String tableName = "dictionary";
	private DictionaryDetails dd; 
	
	private Vector<Object> AbrevationVector =  new Vector<Object>();
	
	private Vector<Object> NewDictionaryVector = new Vector<Object>();/** stores new hashtables for Update.*/
	private Vector<Object> OldDictionaryVector = new Vector<Object>();/** stores old hashtables for Update.*/
	
	private Hashtable<Object,Object> ViewHashtable = new Hashtable<Object, Object>();
	
	public SmsDictionary() {
		// TODO Auto-generated constructor stub
	}
	
	
	/**
	 * initializeToAdd() method is initialize the basic properties of Dictionary class.
	 *  like DictionaryMap, which stores the Dictionary Map. 
	 *  @return PropertyMap.  
	 * */
	public Hashtable<Object,Object> initializeToAdd()
	{
		ExecutionTimer t = new ExecutionTimer();
		 t.start();
		 
		Hashtable<Object,Object> HashM = new Hashtable<Object,Object>();
		
		HashM.putAll(initDictionaryDetails());
		HashM =ConvertToLower.convertHashKey(HashM);
		
		if(HashM.containsKey("errorinput"))
		{
			t.end();
			@SuppressWarnings("unused")
			TimerRecordFile timerFile=new TimerRecordFile("pool.tablename","Dictionary","setObject",t.duration());
			return HashM; 
		}
					
		HashM.put("userid", userid);
		t.end();
		@SuppressWarnings("unused")
		TimerRecordFile timerFile=new TimerRecordFile("pool.tablename","Dictionary","initialize",t.duration());
		return HashM ;		
		
	}
	
	public String checkSize()
	{
		ExecutionTimer t = new ExecutionTimer();
		 t.start();
		String charSize = null;
		GetIdName gin=new GetIdName(sqlDB);
		String dicId=gin.getId("Dictionary"); // It will get the Dictionary Id from Database.
		String charId=gin.getId("charSize"); // It will get the charSize Id from Database.
		try
		{	
			
			Hashtable<Object, Object> table=new Hashtable<Object, Object>();
			table.put("pid", charId);
			table.put("mid", dicId);
			table.put("td","null");
			RecordSearch ps = new RecordSearch(sqlDB);
			ps.setConditionMap(table);
			String line[] = ps.getArrayFromResultSet();
			for(int i=0;i<line.length;i++)
			{	
				String Splitline[] = line[i].split("\t");
				charSize = Splitline[Column.pv_index-1];
				if(charSize.equals("0"))
					charSize = Splitline[Column.vt_index-1];
				else
					charSize = gin.getItem(charSize);
				return charSize; 
			}
		
		}
		catch(Exception e){}
		t.end();
		@SuppressWarnings("unused")
		TimerRecordFile timerFile=new TimerRecordFile("pool.tablename","Dictionary","checkSize",t.duration());
		
		return charSize;
	}
	
	/**
	 * pool::PropertyDetails::initPropertyDetails() method will initialise the each and every properties of the 
	 * request message in the Dictionary odject.
	 * * */
	public Hashtable<Object, Object> initDictionaryDetails()
	{
		ExecutionTimer t = new ExecutionTimer();
		 t.start();
		sqlDB.pLog.Logger.append("\nInitilization of Dictionary Class");			
		String msg = message;
		String PropertySPchar=null;
		int count = 0; 
		ResultSet rs;
		Hashtable<Object,Object> DictionaryMap = new Hashtable<Object,Object>();
		Hashtable<Object, Object> ErrorMap = new Hashtable<Object, Object>();
		
		//GET THE SPECIAL CHARECTOR FOR THE PROPERTY DETAILS
		try
		{
			rs = sqlDB.getSelect("select fieldname,spchar from command where msgtype = '"+request+"' and process = '"+process+"' order by order1");//check for mod --- add process instead add
			rs.next();
			PropertySPchar = rs.getString("spchar");
			int i = 0;
			
			while(i<msg.length())
			{
				char ch = CharAt.CharAT(msg,i);
				if(ch=='"')
				{
					i = msg.indexOf('"',i+1)+1;
					ch = msg.charAt(i);
				}
				
				if(ch == PropertySPchar.toCharArray()[0])
					count ++;
				i++;
			}
			System.out.println("pool::Dictionary::initDictionaryDetails()::Special Char : "+PropertySPchar);
			System.out.println("pool::Dictionary::initDictionaryDetails()::Count : "+count);
		
			rs.close();
		}
		catch (Exception e) 
		{
			System.out.println("pool::Dictionary::initDictionaryDetails():: Exception::");
			e.printStackTrace();
		}
		
		try
		{						
			int cnt = 0;
			sqlDB.pLog.Logger.append("\nDictionary Map : ");
			String abrevation = null;
			
			while(cnt != count)
			{	
				dd = new DictionaryDetails(cnt+1,message,request,sqlDB,process);
				dd.tempDictionaryMap.putAll(dd.DictionaryData());	
				
				Hashtable<Object,Object> tmp = new Hashtable<Object, Object>();
				tmp.putAll(dd.tempDictionaryMap);
				
				if(dd.tempDictionaryMap.containsKey("errorinput"))
					return dd.tempDictionaryMap;
				
				try
				{
					abrevation=dd.tempDictionaryMap.get("abrevation").toString();
						if(!dd.tempDictionaryMap.get("msgid").equals("no$"))
						{
							System.out.println(" abrevation " + dd.tempDictionaryMap.get("abrevation"));				
								
							if(dd.tempDictionaryMap.get("abrevation").equals("no$")==true)
							{
								DictionaryMap.put("ErrorInput", "Please insert valid format *abrevation:msgid");							
								ErrorMap.put("ErrorInput", "Please insert valid format *abrevation:msgid");
								System.out.println("pool::Dictionary ::initDictionaryDetails():: Please insert valid format *abrevation:msgid \n\n");
								sqlDB.pLog.Logger.append("\n pool::Dictionary ::initDictionaryDetails():: " + request + " Please insert valid format *abrevation:msgid \n\n");
							}	
						}
						else
						{
							System.out.println("pool::Dictionary ::initDictionaryDetails():: Please insert valid format *abrevation:msgid \n\n");
							ErrorMap.put("ErrorInput", "Please insert valid format *abrevation:msgid");
							DictionaryMap.put("ErrorInput", "Please insert valid format *abrevation:msgids");						
						}
				}				
				catch (Exception e) 
				{
					System.out.println("pool::Dictionary ::initDictionaryDetails():: Please insert valid format *abrevation:msgid");
					ErrorMap.put("ErrorInput", "Please insert valid format *abrevation:msgid");
					DictionaryMap.put("ErrorInput", "Please insert valid format *abrevation:msgid");
				}
				
				int intSize;
				try 
				{
					intSize = Integer.parseInt(checkSize());
				} catch (Exception e){
					intSize  = 5;
				}
				
				if(userid.equalsIgnoreCase("+911234567891")==false)
				{
					if(abrevation.length()==intSize)
					{
						AbrevationVector.add(tmp);
						//AbrevationVector.add(dd);				
					}
					else
					{
						System.out.println("pool::Dictionary ::initDictionaryDetails():: Please insert abrevation of "+intSize+ " characters");
						ErrorMap.put("ErrorInput", "Please insert abrevation of "+intSize+ " characters");
						DictionaryMap.put("ErrorInput"," Please insert abrevation of "+intSize+ " characters");	
						break;
					}
				}
				else
				{
					AbrevationVector.add(tmp);
					//AbrevationVector.add(dd);
				}
				
				if(ErrorMap.containsKey("ErrorInput"))
					return ErrorMap;
				
				cnt++;
			}
				
		}
		catch(Exception e)
		{
			System.out.println("pool::DictionaryDetails :: initPropertyDetails() :: Exception while creating a property_details object ----");
			e.printStackTrace();
			ErrorMap.put("ErrorInput", " Error ");
			DictionaryMap.put("ErrorInput","Error" );	
			//break;
		}
		t.end();
		@SuppressWarnings("unused")
		TimerRecordFile timerFile=new TimerRecordFile("pool.tablename","Dictionary","initDictionaryDetails",t.duration());
		return DictionaryMap;
	}
	
	
	public StringBuffer initializeToUpdate() 
	{
		ExecutionTimer t = new ExecutionTimer();
		 t.start();
		 
		System.out.println("pool :: Dictionary :: getUpdate()::You are in Update");
		ResultSet rs;// Creating reference variable of Result set.
		Hashtable<Object,Object> newDictionaryMap = new Hashtable<Object,Object>();
		Hashtable<Object,Object> oldDictionaryMap = new Hashtable<Object,Object>();
		Command cp = new Command(request,sqlDB);
		SpecialCharacter sp=new SpecialCharacter();
		String spcharMod = null, spcharAdd = null, spCharColon = null;				
		int charFlag = 0;
		int index_firstSpchar = sp.getNextSpChar(0, message.toCharArray());
		
		String spChar = "" + CharAt.CharAT(message, 0);
		
		
		try
		{
			// It will fetch the special character for the mod process.
			rs = sqlDB.getSelect("select fieldname,spchar from command where msgtype = '" + request + "' and process ='" + process + "' order by order1");
			while(rs.next())
			{
				String spchar = rs.getString("spchar");				
				if(spChar.equals(spchar)==true)
				{
					spcharMod = spChar;
					charFlag=1;
					break;
				}					
			}
			if(charFlag==0) // If first special character is not for the mod operation then message will generate.
			{
				sbrDTB.append("pool::Dictionary::getUpadte():: Message is not in proper sequence.");
				System.out.println("pool::Dictionary::getUpadte():: Message is not in proper sequence.");
				return sbrDTB;
			}
			rs.close();
			
			try
			{
				// It will fetch the second special character of the Add process.
				rs = sqlDB.getSelect("select spchar from command where msgtype = '" + request +"' and process = 'add' and spchar is not null order by order1 desc");
				rs.next();
				spCharColon = rs.getString("spchar");								
				rs.close();
			}catch (SQLException e2){ }
			
			// It will fetch the special character of the Add process.
			rs = sqlDB.getSelect("select fieldname,spchar from command where msgtype = '" + request + "' and process = 'add' order by order1");
			while(rs.next())
			{
				String spchar = rs.getString("spchar");				
				if(message.contains(rs.getString("spchar")))
				{
					System.out.println("SPCHAR "+ spchar);
					spcharAdd = spchar;
					break;
				}
			}
			rs.close();
			
		}
		catch (Exception e) 
		{
			System.out.println("pool::Dictionary::getUpadte():: Exception while fetching special character");
		}
		
		int i=0, count=0, cnt=0, index=0, index_star = 0,start=0,end=0;
		// It will get count the special characters for the update() process.
		
		String msg=message;
		while(i<msg.length())
		{				
			char ch = CharAt.CharAT(msg,i);
			if(ch == spcharMod.toCharArray()[0])
				count ++;
			i++;
		}
				
		System.out.println("pool::Dictionary::getUpdate():: Special Char : "+spcharMod);
		System.out.println("pool::Dictionary::getUpdate():: Count : "+count);		
		
		
		while(cnt != count)
		{
			System.out.println("Count" + cnt + "\n Message in pool :: Dictionary :: getUpdate():: " + message);
			oldDictionaryMap = new Hashtable<Object,Object>();
			newDictionaryMap = new Hashtable<Object,Object>();
			Hashtable<Object, Object> msgidMap = new Hashtable<Object, Object>();
			
			int index_nextSpchar = Index.indexOf(message, spChar, index_firstSpchar+1);
			
			String stsStr = null; 
			
			if(index_nextSpchar == -1)
			{
				stsStr = message.substring(start);
				//stsStr = cp.getLastProperty(msg, Request, "add");
				index_nextSpchar = end;
			}
			else
			{	
				stsStr = message.substring(index_firstSpchar, index_nextSpchar);
			}
			
			System.out.println("StoS String -->> " + stsStr);
			
			// It will check the "$" and ":" special characters into the string. 
			if(stsStr.contains(spcharAdd)==true && stsStr.contains(spCharColon)==true)
			{	
				//String retStr = null;
				//index_start = Index.indexOf(message, spChar,index); // It will stores the index of "*".
				start = Index.indexOf(message, spcharMod, index);  // It will stores the index of ":".
				end = Index.indexOf(message, spCharColon, index); // It will stores the index of "$".		
				
				String oldDic = message.substring(end, sp.getNextSpChar(end, message.toCharArray()));
				System.out.println(" Old Word -- >> " + oldDic);	
									
					oldDictionaryMap = cp.getHashCommand(request, oldDic,"add");
					
					Dictionary objDict = new Dictionary(sqlDB,userid);
					oldDictionaryMap.putAll(objDict.replaceAbrevation(oldDictionaryMap));
					
					if(oldDictionaryMap.containsKey("ErrorInput"))
					{
						return sbrDTB.append(oldDictionaryMap.toString());
					}
					oldDictionaryMap.put("userid",userid);
					
					
				//newDictionaryMap.put("msgid", msgid);
				
				
				String newDic = message.substring(start, sp.getNextSpChar(start, message.toCharArray()));
				System.out.println(" New Word -- >> " + newDic);				
				
				newDictionaryMap = cp.getHashCommand(request, newDic,process); 
				if(newDictionaryMap.containsKey("ErrorInput"))
				{
					return sbrDTB.append(newDictionaryMap.toString());
				}
				newDictionaryMap.put("userid",userid);
					
				String abrevation=newDictionaryMap.get("abrevation").toString();					
				int intSize = 0;
				try 
				{
					intSize = Integer.parseInt(checkSize());
				} catch (Exception e){
					intSize  = 5;
				}
				
				if(abrevation.length()!=intSize)
				{
					 System.out.println(" pool::Dictionary::getUpadte():: "+newDic + " is not of proper size.");
	   				 sqlDB.pLog.Logger.append("\n pool::Dictionary::getUpadte():: "+newDic + " is not of proper size.");
	   				 sbrDTB.append(" pool::Dictionary::getUpadte():: "+newDic + " is not of proper size.");
	   				 newDic="";
				}
				index_star = Index.indexOf(message, spcharAdd, index);
				String msgid = message.substring(index_star, sp.getNextSpChar(index_star, message.toCharArray()));
				msgidMap = cp.getHashCommand(request,msgid,process);
				
				if(msgidMap.containsKey("msgid") == true)
				{
					msgid = msgidMap.get("msgid").toString();
					System.out.println("Msgid -- >>" + msgid);
					newDictionaryMap.put("msgid", msgid);
					oldDictionaryMap.put("msgid", msgid);
				}
				
				System.out.println(" pool::Dictionary::getUpadte():: New Dictionary word : " + newDictionaryMap + " & Old Dictionary word " + oldDictionaryMap);
				
				cnt++;
			}
			else
			{
				try
				{	
					
					start = Index.indexOf(message, spcharAdd,index+1); // It will stores the index of "*" or ":".
					end = Index.indexOf(message, spcharMod, index+1); // It will stores the index of "$" or ",".							
					
					String newDic = message.substring(0,start);
					System.out.println(" New Word -- >> " + newDic);				
					newDictionaryMap = cp.getHashCommand(request, newDic,process); //new
					if(newDictionaryMap.containsKey("ErrorInput"))
				 	{
						return new StringBuffer(newDictionaryMap.toString());
					}
					newDictionaryMap.put("userid",userid);					
					
					String oldDic = message.substring(start);
					System.out.println(" Old Word -- >> " + oldDic);
					oldDictionaryMap = cp.getHashCommand(request, oldDic,"add"); //old
					if(oldDictionaryMap.containsKey("ErrorInput"))
				 	{
						return new StringBuffer(oldDictionaryMap.toString());
					}
					oldDictionaryMap.put("userid",userid);	
					
					System.out.println(" New Dictionary word : " + newDictionaryMap + " & Old Dictionary word " + oldDictionaryMap);
										
					cnt++;
				}
				catch(Exception e)
				{
					System.out.println("pool::Dictionary::getUpadte():: Exception ");
					e.printStackTrace();
				}
			}	
			
			OldDictionaryVector.add(oldDictionaryMap);
			NewDictionaryVector.add(newDictionaryMap);
		}
		t.end();
		@SuppressWarnings("unused")
		TimerRecordFile timerFile=new TimerRecordFile("pool.tablename","Dictionary","getUpdate",t.duration());
		
		return sbrDTB;
	}
	
	public StringBuffer initializeToView() 
	{
		ExecutionTimer t = new ExecutionTimer();
		 t.start();
		StringBuffer sbrProperty=new StringBuffer();
		Hashtable<Object, Object> Dictionaryhash = new Hashtable<Object, Object>();
		
		Command cp = new Command(tableName, sqlDB);
		Dictionaryhash = cp.getHashCommand(tableName,message,process); 
		
		Dictionary objDict = new Dictionary(sqlDB,userid);
		Dictionaryhash.putAll(objDict.replaceAbrevation(Dictionaryhash));
		
		if(Dictionaryhash.containsKey("ErrorInput"))
		{
			sbrProperty.append(Dictionaryhash.get("ErrorInput"));
			return sbrProperty;
		}
		ViewHashtable.putAll(Dictionaryhash);
		
		
		t.end();
		@SuppressWarnings("unused")
		TimerRecordFile timerFile=new TimerRecordFile("pool.tablename","Dictionary","getView",t.duration());
		
		return sbrProperty;
	
	}
	
	
	public Vector<Object> getPropertyVector(){
		return AbrevationVector;
	}
	
	public Vector<Object> getOldPropertyVector() {
		
		return OldDictionaryVector;
	}
	
	public Vector<Object> getNewPropertyVector() {
		
		return NewDictionaryVector;
	}
	public Hashtable<Object,Object> getViewHashtable() {
		return ViewHashtable;
	}


	public Hashtable<Object, Object> initializeToDelete() {
		// TODO Auto-generated method stub
		return null;
	}
}
